﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json.Linq;

namespace NetOrientDB.ObjectModel
{
	internal class PropertiesParser
	{
		public IDictionary<string, object> Parse(string jsonData)
		{
			var rootObject = JObject.Parse(jsonData);
			return Parse(rootObject);
		}

		public IDictionary<string, object> Parse(JObject obj)
		{
			// Create a new dictionary
			var dictionary = new Dictionary<string, object>();

			foreach (var child in obj.Properties())
			{
				ParseProperty(child, dictionary);
			}

			return dictionary;
		}

		private object ParseToken(JToken token)
		{
			switch (token.Type)
			{
				case JTokenType.Object:
					return Parse((JObject)token);
				case JTokenType.Array:
					return ParseArray(token);
				case JTokenType.Integer:
					return token.Value<int>();
				case JTokenType.Float:
					return token.Value<float>();
				case JTokenType.String:
					return token.Value<string>();
				case JTokenType.Boolean:
					return token.Value<bool>();
				case JTokenType.Date:
					return token.Value<DateTime>();
				case JTokenType.Raw:
					return token.Value<byte[]>();
				case JTokenType.Bytes:
					return token.Value<byte[]>();
				case JTokenType.Null:
					return null;
				default:
					throw new ArgumentOutOfRangeException();
			}
		}

		private ICollection<object> ParseArray(JToken array)
		{
			// Create a new collection
			var collection = new List<object>();

			foreach (var child in array.Children())
			{
				collection.Add(ParseToken(child));
			}

			return collection;
		}

		private void ParseProperty(JProperty property, IDictionary<string, object> dictionary)
		{
			dictionary.Add(property.Name, ParseToken(property.Value));
		}
	}
}
